using System;
using System.Collections.Generic;
using System.Text;

namespace AIFSDataAccessLayer.Utilities
{
    /// <summary>
    /// Utility class that helps in converting primitive type operations.
    /// </summary>
    public static class TypeUtil
    {
        public enum DateFormatSupported
        {
            DD_MMM_YYYY_DASH_SEPERATED
        }

        #region ValueOrDBNull
        public static object ValueOrDBNull<T>(Nullable<T> nullable) where T : struct
        {
            if (!nullable.HasValue)
                return System.DBNull.Value;
            else
                return nullable.Value;
        }

        public static object ValueOrDBNull(DateTime? date)
        {
            if (!date.HasValue)
                return System.DBNull.Value;

            return ValueOrDBNull(date.Value);
        }

        public static object ValueOrDBNull(DateTime date)
        {
            if (date == DateTime.MinValue)
                return System.DBNull.Value;
            else
                return date;
        }

        public static object ValueOrDBNull(DateTime? date, DateFormatSupported dateFormat)
        {
            if (!date.HasValue)
                return System.DBNull.Value;
            else
                return ValueOrDBNull(date.Value, dateFormat);
        }

        public static object ValueOrDBNull(DateTime date, DateFormatSupported dateFormat)
        {
            if (ValueOrDBNull(date) == System.DBNull.Value)
                return System.DBNull.Value;
            else
            {
                string formatString = "d"; // 01/03/2008
                switch (dateFormat)
                {
                    case DateFormatSupported.DD_MMM_YYYY_DASH_SEPERATED:
                        formatString = "dd-MMM-yyyy"; //03-JAN-2008
                        break;
                }

                return date.ToString(formatString, System.Globalization.DateTimeFormatInfo.InvariantInfo);
            }
        }

        public static object ValueOrDBNull(int num)
        {
            if (num == int.MinValue)
                return System.DBNull.Value;
            else
                return num;
        }

        public static object ValueOrDBNull(string val)
        {
            return ValueOrDBNull(val, false);
        }

        /// <summary>
        /// If preserveCase is true, the case of the string will be preserved.
        /// If not it will act like ValueOrDBNull(string) and convert all to upper
        /// </summary>
        /// <param name="val"></param>
        /// <param name="preserveCase"></param>
        /// <returns></returns>
        public static object ValueOrDBNull(string val, bool preserveCase)
        {
            if (string.IsNullOrEmpty(val))
            {
                return System.DBNull.Value;
            }
            else
            {
                if (preserveCase)
                    return val;
                else
                    return val.ToUpper();
            }
        }

        public static object ValueOrDBNull(Enum eNum)
        {
            string eName = Enum.GetName(eNum.GetType(), eNum);
            if (eName == "UNSET")
                return System.DBNull.Value;
            else
                return eName;
        }
        #endregion

        #region ValueOrNull

        public static object ValueOrNull(int? num)
        {
            if (!num.HasValue)
                return null;
            else
            {
                return ValueOrNull(num.Value);
            }
        }

        public static object ValueOrNull(DateTime? num)
        {
            if (!num.HasValue)
                return null;
            else
            {
                return ValueOrNull(num.Value);
            }
        }

        public static object ValueOrNull(DateTime date)
        {
            if (date == DateTime.MinValue)
                return null;
            else
                return date;
        }

        public static object ValueOrNull(DateTime date, DateFormatSupported dateFormat)
        {
            if (ValueOrNull(date) == null)
                return null;
            else
            {
                string formatString = "d"; // 01/03/2008
                switch (dateFormat)
                {
                    case DateFormatSupported.DD_MMM_YYYY_DASH_SEPERATED:
                        formatString = "dd-MMM-yyyy"; //03-JAN-2008
                        break;
                }

                return date.ToString(formatString, System.Globalization.DateTimeFormatInfo.InvariantInfo);
            }
        }

        public static object ValueOrNull(int num)
        {
            if (num == int.MinValue)
                return null;
            else
                return num;
        }

        /// <summary>
        /// Returns the object or null. Value is converted to all upper cases. Use the overload method with preserveCase set to true.
        /// </summary>
        public static object ValueOrNull(string val)
        {
            return ValueOrDBNull(val, false);
        }

        public static object ValueOrNull(Enum eNum)
        {
            string eName = Enum.GetName(eNum.GetType(), eNum);
            if (eName == "UNSET")
                return null;
            else
                return eName;
        }
        #endregion

        #region Convert Generic arrays
        public static string[] IntToStringArray(int[] Values)
        {
            if (Values != null && Values.Length > 0)
            {
                List<int> valInts = new List<int>();
                valInts.AddRange(Values);
                List<string> retVals = valInts.ConvertAll<string>(new Converter<int, string>(intToString));
                return retVals.ToArray();
            }

            return new string[] { };
        }

        public static int[] StringToIntArray(string[] Values)
        {
            if (Values != null && Values.Length > 0)
            {
                List<string> valStrings = new List<string>();
                valStrings.AddRange(Values);
                List<int> retVals = valStrings.ConvertAll<int>(new Converter<string, int>(stringToInt));
                return retVals.ToArray();
            }

            return new int[] { };
        }

        private static string intToString(int value)
        {
            return value.ToString();
        }

        private static int stringToInt(string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                int val = 0;
                bool ret = int.TryParse(value, out val);
                if (ret)
                    return val;
            }

            throw new InvalidCastException("String value provided can not be converted to integer");
        }
        #endregion
    }
}
